package com.longxiao.service;

import com.longxiao.enums.ResultCode;
import com.longxiao.enums.UserType;
import com.longxiao.exception.LXException;
import com.longxiao.service.message.SmsSender;
import com.longxiao.service.util.RedisClient;
import com.longxiao.vo.SendSmsPo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * Created by yusong on 2017/5/25.
 * 短信服务
 */
@Service
public class SmsService {

    private static Logger logger = LoggerFactory.getLogger(SmsService.class);
    //一天发送短信次数
    private static int DAY_LIMITS = 10;
    //计数缓存前缀
    private static String DAY_LIMIT_INDEX_PREFIX = "longxiao:sms:times:";
    //计数有效时间
    private static int DAY_LIMIT_TTL = 3600*24;
    //短信有效时间
    private static int SMS_VALID_TIME = 60*2;
    //短信验证码缓存前缀
    private static String SMS_CODE_PREFIX = "longxiao:sms:code:";

    @Autowired
    private RedisClient redisClient;
    @Autowired
    private SmsSender smsSender;


    /*
    *发送短信
    */
    public void sendSms(SendSmsPo sendSmaPo ) throws LXException {
        logger.info("sendSms|发送短信验证码|mobile:"+sendSmaPo);
        if(!checkLimit(sendSmaPo.getMobile())){
            logger.warn("sendSms|短信频率发送超过次数|"+sendSmaPo);
            if (UserType.Tch.getCode() == sendSmaPo.getUserType()){
                throw new LXException(ResultCode.SMS_EXCEED_LIMIT.code,ResultCode.SMS_EXCEED_LIMIT.getEn());
            }else{
                throw new LXException(ResultCode.SMS_EXCEED_LIMIT.code,ResultCode.SMS_EXCEED_LIMIT.getCn());
            }
        }
        String code = generateCode(sendSmaPo.getMobile());
        String smsContent = null;
        if (UserType.Tch.getCode() == sendSmaPo.getUserType()){
            smsContent = "Your LongXiao Online Study SMS code is" +code +", valid in two minutes.";
        }else{
            smsContent = "你的龙校在线教育注册码为：" +code +",两分钟内有效。";
        }
        try {
            smsSender.send(sendSmaPo.getMobile(),smsContent,"");
        } catch (Exception e) {
            logger.error("sendSms|短信发送失败|"+sendSmaPo,e);
            if (UserType.Tch.getCode() == sendSmaPo.getUserType()){
                throw new LXException(ResultCode.SMS_EXCEED_LIMIT.code,ResultCode.SMS_EXCEED_LIMIT.getEn());
            }else{
                throw new LXException(ResultCode.SMS_EXCEED_LIMIT.code,ResultCode.SMS_EXCEED_LIMIT.getCn());
            }
        }


    }

    /*
    *检查短信验证码
    */
    public boolean checkCode(String mobile, String code) throws LXException{
        String key = SMS_CODE_PREFIX+mobile;
        String storeCode = redisClient.get(key);
        if(StringUtils.isEmpty(storeCode)){
            logger.error("checkCode|短信验证码已经失效|mobile:"+mobile);
            throw new LXException(ResultCode.SMS_EXPIRE.code,ResultCode.SMS_EXPIRE.getCn());
        }
        logger.info("checkCode|检查验证码|storeCode:"+storeCode+"|code:"+code);
        return storeCode.endsWith(code);
    }



    /*
    *检查发短信频次
    */
    private boolean checkLimit(String mobile){
        String key = DAY_LIMIT_INDEX_PREFIX+mobile;
        Long times = redisClient.incr(key);
        logger.info("checkLimit|mobile:"+mobile+"|短信次数:"+times);
        if(times == 1){
            redisClient.expire(key,DAY_LIMIT_TTL);
            return Boolean.TRUE;
        }else if(times <= DAY_LIMITS){
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }


    /*
    *生成短信验证码,并存储到redis
    */
    private String generateCode(String mobile){
        String code = "123456";
        String key = SMS_CODE_PREFIX+mobile;
        redisClient.setEx(key,code,SMS_VALID_TIME);
        return code;
    }

}
